<?php
namespace gnomephp\captcha;

abstract class CaptchaController extends \gnomephp\mvc\CoreController{

	const MAX_IMAGE_WIDTH = 600;
	const MAX_IMAGE_HEIGHT = 600;
	
	
	/**
	 * Should return the length of the captcha.
	 */
	protected function getCaptchaLength(){
		return 6;
	}
	
	
	/**
	 * Shows captcha image.
	 */
	public function index($name, $width, $height){

		$width = (int)$width;
		$height = (int)$height;
		if ($width > CaptchaController::MAX_IMAGE_WIDTH || $height > CaptchaController::MAX_IMAGE_HEIGHT) die("Max height is 600 and width 600.");
		
		
		// prevent caching
		header('Expires: Tue, 08 Oct 1991 00:00:00 GMT');
		header('Cache-Control: no-cache, must-revalidate');

		// output the image
		header("Content-Type: image/gif");
		
		
		$image = $this->getImage($name, $width, $height, $this->getCaptchaLength());
		imagegif($image);
		imagedestroy($image);
	}

	protected function getImage($name, $width = 120, $height = 30, $length = 6){
		
		// Get a random code.
		$code = CaptchaController::generateRandomValue($length);
		
		// Set session.
		$this->session->set(Captcha::getSessionName($name), Captcha::getValue($code));
		$this->session->save();
		
		// colors
		$r = mt_rand(160, 255);
		$g = mt_rand(160, 255);
		$b = mt_rand(160, 255);
		// create handle for new image
		$image = imagecreate($width, $height);
		// create color handles
		$background = imagecolorallocate($image, $r, $g, $b);
		$color = imagecolorallocate($image, $r-128, $g-128, $b-128);
		// fill the background
		imagefill($image, 0, 0, $background);

		// add characters in random orientation
		for($i = 1; $i <= $length; $i++){
			$counter = mt_rand(0, 1);
			if ($counter == 0){
				$angle = mt_rand(0, 18);
			}
			if ($counter == 1){
				$angle = mt_rand(18, 40);
			}

			// "arial.ttf" can be replaced by any TTF font file stored in the same directory as the script

			// points = pixels * 72 / 96
			$size = ((($width / $length)) * 72) / 96;
			

			$x = ($i * $size) - 8;
			
			$y = ( $height / 1.5 );
			imagettftext(
				$image, 
				$size, 
				$angle, 
				$x, 
				$y, 
				$color, 
				(GNOME_FW_PATH . DIRECTORY_SEPARATOR .  'res' . DIRECTORY_SEPARATOR . 'font' . DIRECTORY_SEPARATOR . 'arial.ttf'), 
				substr($code, ($i - 1), 1)
			);
		}

		// draw a line through the text
		imageline($image, 0, mt_rand(5, $height-5), $width, mt_rand(5, $height-5), $color);
		imageline($image, 0, mt_rand(0.1 *$height, $height), mt_rand(0.1 * $width, $width), 0, $color);
		
		// blur the image
		$gaussian = array(array(1.0, 2.0, 1.0), array(2.0, 4.0, 2.0), array(1.0, 2.0, 1.0));
		imageconvolution($image, $gaussian, 16, 0);

		// add a border for looks
		imagerectangle($image, 0, 0, $width - 1, $height - 1, $color);

		return $image;
	}



	static public function generateRandomValue($length = 6, $chars = 'ABCDEFGHJKLMNPQRSTUV2345689'){
		// generate the random code
		$code = '';
		for($i = 0; $i < $length; $i++){
			$pos = mt_rand(0, strlen($chars)-1);
			$code .= substr($chars, $pos, 1);
		}
		
		
		return $code;
	}



}
